/**
 * @FilePath     : /src/lgmg_robots/agv_navigation/agv_navigate/include/agvNavigate/profiler.h
 * @Description  : Profiler类，负责处理与速度规划相关的功能，包括当前值、结束值、工作模式等的管理。 
 *                 提供了创建、加载、设置和获取各种参数的方法，以及检查配置状态的功能。 
 * @Author       : xiujun.yang
 * @Version      : 1.0.0
 * @LastEditors  : haibo haibo.yang@lgmgim.cn
 * @LastEditTime : 2024-12-19 16:18:51
 * @Copyright (c) 2024 by 临工智能信息科技有限公司, All Rights Reserved. 
**/
#pragma once
#include <atomic>
#include "z_types.h"
#include "geometry.h"
#include "offline_scurve_plan.h"
//////////////////////////////////////////////////////////////////////////////
// The interface of class "CProfiler".
class Profiler {
 public:
   // Default constructor
    Profiler(): 
        cruise_value_(0.0f),
        cycle_(0.05f),
        cur_value_(0.0f),
        end_value_(0.0f),
        area_(0.0f),
        area_record_(0.0f),
        mode_(0),
        done_(false),
        stage_(-1),
        type_(-1),
        planner_(nullptr),
        replan_(false) {}

    // Create the object
    void Create(float cruise_value, float refrain_value, float up_slope, float dn_slope,
          float up_small_slope, float down_small_slope, float tran_value, float cycle, short type,
          float sure_area = 0.0f, float search0_value = 0.0f);

    // Set the current work mode
    void SetMode(int mode) { if (planner_) planner_->plan_mode_.setMode(mode); }
    
    // Get the current work mode
    int GetMode() const;

    // Set new current value,
    void Load(float cur_value, float end_value, float area);

    // Set up planner
    bool SetUpPlanner(OfflineScurvePlan* planner);

    // Load new area
    void ReloadArea(float area) { 
      if (!done_) { 
        area_ = area; 
        DEBUG_OUT("ReloadArea:" << ",m_fArea=" << area_);
      }
    };

    // Set new end value
    void SetEndValue(const float end_value) { end_value_ = end_value; };

    // Get new end value
    float GetEndValue() const { return end_value_; };

    // Generate output automatically
    float LimitGenerate(float limit);

    // Retrieve the current value
    float GetCurValue() const { return cur_value_; }

    // Set the current value
    void SetCurValue(float value) { cur_value_ = value; }

    // Retrieve the area left
    float GetCurArea() const { return area_; }

    // Set the area left
    void SetCurArea(float area) { area_ = area; }

    // Test whether the last profile have been finished
    bool Done() const { return done_; }

    // Get the end value of application
    float GetAppEndValue() { return end_value_; };

    // Get theoretical remaining distance
    float GetTheoryArea();

 private:
    float cruise_value_; // Cruise value (>0)
    float cycle_;        // The control cycle in "second"
    float cur_value_;    // The current value
    float end_value_;    // The required end value (>=0)
    float area_;         // The total area to be covered
    float area_record_;  // Current total area record
    int mode_;           // Work mode: 0-normal; 1-suspended; 2-compel
    bool done_;          // Whether the profile is finished
    short stage_;        // In which working stage
    int type_;           // The type of profile
    OfflineScurvePlan* planner_; // Global speed planner
    bool compensated_;           // Compensation flag
    std::atomic<bool> replan_;   // Replan flag;
};